from Tkinter import Canvas
from Tkconstants import NW

import ImageTk

class ImageCanvas(Canvas):

    def __init__(self, master, **options):
        Canvas.__init__(self, master, **options)
        self.master = master
        self.image = None
        self.photo = None
        
        self.bind("<B1-Motion>", self.mouseMotion)
        self.bind("<Button-1>", self.mousePressed)
        self.bind("<ButtonRelease-1>", self.mouseReleased)
        
        self.mouseStartX = 0
        self.mouseStartY = 0
        self.mouseEndX = 0
        self.mouseEndY = 0
        
        self.rectangleId = None
       
    def setImage(self,image):
        self.image = image
        self.config(width=self.image.size[0])
        self.config(height=self.image.size[1]) 
        self.photo = ImageTk.PhotoImage(self.image)
        self.create_image(0, 0, anchor=NW, image=self.photo)
 
    def mousePressed(self,event):
        self.delete(self.rectangleId)
        self.mouseStartX = self.canvasx(event.x)
        self.mouseStartY = self.canvasx(event.y)

    def mouseMotion(self,event):
        self.delete(self.rectangleId)
        currentX = fitIntoBoundaries(self.canvasx(event.x), 3, \
                                     self.image.size[0])
        currentY = fitIntoBoundaries(self.canvasx(event.y), 3, \
                                     self.image.size[1])
        self.rectangleId = self.create_rectangle(self.mouseStartX, \
                                                 self.mouseStartY, \
                                                 currentX, \
                                                 currentY) 
           
    def mouseReleased(self,event):
        self.mouseEndX = event.x
        self.mouseEndY = event.y

    def getRectangle(self):
        return (self.mouseStartX, self.mouseStartY, \
                 self.mouseEndX, self.mouseEndY)


def fitIntoBoundaries(v, lower, upper):
    if v > upper:
        v = upper
    if v < lower:
        v = lower
    return v
